<?php
/**
 * 分库分表
 * 分表前需给总表增加一个分表次数字段。
 * ALTER TABLE `table_name` ADD `nns_move_num` int(2) NOT NULL DEFAULT 0;
 */
header("Content-Type:text/html;charset=utf-8");
include_once dirname(dirname(dirname(__FILE__)))."/nn_logic/nl_common.func.php";
set_time_limit(0);
ini_set('memory_limit', '2048M');
$argv = $_GET;
$database = $argv[1];
$table_name = $argv[2];
$limit = (!isset($argv[3]) || empty($argv[3])) ? 1000 : $argv[3];
//是否开启分表执行次数控制, 0关闭，其他开启
$move_num_enabled = (!isset($argv[5]) || empty($argv[5])) ? false : true;
//分表次数设置后，此值无作用，默认为0
$begin = (!isset($argv[4]) || empty($argv[4]) || $move_num_enabled) ? 0 : $argv[4]; 
//执行分表次数包含设置值,参数5开启后才起作用
$move_num = (!isset($argv[6]) || empty($argv[6])) ? 0 : $argv[6];
//在分表次数开关关闭后，是否强制写入总表次数(分表次数开启后此参数无效)  0或者不设置为不写入，其他写入
$force_write = (!isset($argv[7]) || empty($argv[7])) ? false : true;

var_dump($argv);

msg("==========================move data to hash table begin===================");
if (empty($database) || empty($table_name) )
{
	msg("argv is empty");
}


script($database,$table_name,$limit,$begin,$move_num_enabled,$move_num,$force_write);

function script($database,$table_name,$limit,$begin,$move_num_enabled=false,$move_num=0,$force_write=false)
{
	//初始化执行条数
	//$execute_num = $begin;
	$execute_num = 0;

	if ($database == "cms")
	{
		$func_name = "nl_get_dc";
	}else
	{
		$func_name = "nl_get_{$database}_dc";	
	}

	if (!defined('g_db_hash_table_rules'))
	{
		msg("rules is empty");
		return;
	}

	if (!function_exists($func_name))
	{
		msg($func_name." is not exsists");
		return;
	}

	$dc1 = $func_name(array('db_policy'=>NL_DB_WRITE));

	$dc2 = $func_name(array('db_policy'=>NL_DB_WRITE),array('db_type'=>NP_DB_TYPE_HASH_TABLE_MYSQL,'db_hash_table_modes'=>array()));

	$sql_builder = new np_sql_builder($table_name);	
	
	$sql = " show columns from ".$table_name;
    $table_field_maps = nl_query_by_db($sql,$dc2->db());
    unset($sql_builder);

    //自动增加字段？？暂时不考虑,数据太多执行太慢
//     $move_num_bool = true;
//     foreach ($table_field_maps as $field)
//     {
//     	if($field["Field"] === 'nns_move_name')
//     	{
//     		$move_num_bool = false;
//     		break;
//     	}
//     }
//     if($move_num_bool)
//     {
//     	$alter_sql = "ALTER TABLE `{$table_name}` ADD `nns_move_num` int(2) NOT NULL DEFAULT 0";
//     	nl_execute_by_db($alter_sql, $dc1->db());
//     	unset($alter_sql);
//     }
    
	while(true)
	{
		$sql_builder = new np_sql_builder($table_name);
		if($move_num_enabled)
		{
			$sql_1 = $sql_builder->custom_where(array("nns_move_num <= {$move_num}"))->limit($begin,$limit)->query();
		}
		else
		{
			$sql_1 = $sql_builder->limit($begin,$limit)->query();			
		}
		
		$data = nl_query_by_db($sql_1,$dc1->db());
		echo $sql_1;
		if ($data === true)
		{
			unset($sql_builder,$data);
			break;
		}
		$id_arr = array();

		foreach ($data as $key=>&$item)
		{
			foreach ($table_field_maps as $field)
			{
				$field_name = $field["Field"];
	            $field_must = $field["Null"]==="NO"?TRUE:FALSE;
	            $field_default = $field["Default"];
	            $field_type = $field["Type"];
	            if ((strpos($field_type,"int")===0 || strpos($field_type,"float")===0))
	            {
	            	$item[$field_name] = empty($item[$field_name])?0:(int)$item[$field_name];
	            }
	            else if (strpos($field_type,"date")===0)
	            {
	            	$item[$field_name] = empty($item[$field_name])?np_sql_builder::NP_PARAMS_NULL:$item[$field_name];
	            }
	            else
	            {
	            	$item[$field_name] = addslashes($item[$field_name]);
	            }				
			}
			$id_arr[] = $item["nns_id"];
			unset($item['nns_move_num']);
		}
		$sql_2 = $sql_builder->m_replace($data);
		//echo $sql_2;	
		$result = nl_execute_by_db($sql_2,$dc2->db()); 
		if ($result === false)
		{
			unset($sql_builder,$data,$ids);
			msg($sql_2." execute fail![db error]".$dc2->db()->last_error_desc());
			break;
		}
		//总表执行次数计算开关
		if($move_num_enabled || $force_write)
		{
			if(!$move_num_enabled && $force_write) //当计算执行次数关闭，强制写入打开时
			{
				$ids = implode("','", $id_arr);
				$sql_3 = "UPDATE `{$table_name}` SET `nns_move_num` = nns_move_num+1 WHERE `nns_id` IN ('{$ids}')";
			}
			else 
			{
				$num = $move_num + 1;
				$sql_3 = $sql_builder->where(array('nns_id' => $id_arr))->update(array('nns_move_num' => $num));
			}
			//echo $sql_3;
			$result_3 = nl_execute_by_db($sql_3,$dc1->db());
			if ($result_3 === false)
			{
				unset($sql_builder,$data,$result,$ids,$sql_3);
				msg($sql_3." execute fail![db error]".$dc1->db()->last_error_desc());
				break;
			}
			unset($num,$sql_3,$result_3);
		}
		if($move_num_enabled)
		{
			if (count($data) < $limit )
			{
				$execute_num += count($data);
			}
			else
			{
				$execute_num += $limit;
			}			
		}
		else 
		{
			$begin += $limit;
			if (count($data) < $limit )
			{
				$execute_num += count($data);
			}
			else
			{
				$execute_num += $limit;
			}
		}

		msg("{$execute_num} is complete\n");
		unset($sql_builder,$data,$result,$ids);
	}
}

    /**
     * 日志记录方法
     */
    function msg($msg)
    {
        if(empty($msg))
        {
            return false;
        }
        echo date('Y-m-d H:i:s') . "   " . $msg . "\r\n<br/>";
        //写入日志文件
        $str_cms_dir = dirname(dirname(dirname(__FILE__))) . '/';
        $str_log_dir = $str_cms_dir . 'data/log/nn_script/script_move_data_to_hash_table/' . date("Ymd") . "/";
        $str_log_file = date("H") . '.txt';
        $str_start_time = "[" . date("Y-m-d H:i:s") . "]";
        if(!is_dir($str_log_dir))
        {
            mkdir($str_log_dir, 0777, true);
        }
        file_put_contents($str_log_dir . $str_log_file, $str_start_time . $msg . "\r\n", FILE_APPEND);
    }
